// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Engine/DeveloperSettingsBackedByCVars.h"
#include "GameplayTagContainer.h"
#include "LyraPlatformEmulationSettings.generated.h"

struct FPropertyChangedEvent;

/**
 * 平台模拟设置
 */
UCLASS(config=EditorPerProjectUserSettings, MinimalAPI)
class ULyraPlatformEmulationSettings : public UDeveloperSettingsBackedByCVars
{
	GENERATED_BODY()

public:
	ULyraPlatformEmulationSettings();

	//~UDeveloperSettings interface
	/**
	 * 获取设置分类名称
	 * @return 分类名称，返回项目名称
	 */
	virtual FName GetCategoryName() const override;
	//~End of UDeveloperSettings interface

	/**
	 * 获取模拟的基础设备配置文件名称
	 * @return 设备配置文件名称
	 */
	FName GetPretendBaseDeviceProfile() const;
	/**
	 * 获取模拟的平台名称
	 * @return 平台名称
	 */
	FName GetPretendPlatformName() const;

private:
	// 要启用的额外平台特性标签容器
	UPROPERTY(EditAnywhere, config, Category=PlatformEmulation, meta=(Categories="Input,Platform.Trait"))
	FGameplayTagContainer AdditionalPlatformTraitsToEnable;

	// 要抑制的额外平台特性标签容器
	UPROPERTY(EditAnywhere, config, Category=PlatformEmulation, meta=(Categories="Input,Platform.Trait"))
	FGameplayTagContainer AdditionalPlatformTraitsToSuppress;

	// 模拟的平台名称
	UPROPERTY(EditAnywhere, config, Category=PlatformEmulation, meta=(GetOptions=GetKnownPlatformIds))
	FName PretendPlatform;

	// 在模拟来自ULyraSettingsLocal的设备特定设备配置文件时，要模拟使用的基础设备配置文件
	UPROPERTY(EditAnywhere, config, Category=PlatformEmulation, meta=(GetOptions=GetKnownDeviceProfiles, EditCondition=bApplyDeviceProfilesInPIE))
	FName PretendBaseDeviceProfile;

	// 我们是否在PIE中应用桌面风格的帧率设置？
	//（帧率限制是引擎范围的设置，因此在编辑器中启用并不总是可取的）
	// 如果测试后台帧率限制，您可能还想禁用编辑器偏好设置"在后台时使用较少的CPU"
	UPROPERTY(EditAnywhere, config, Category=PlatformEmulation, meta=(ConsoleVariable="Lyra.Settings.ApplyFrameRateSettingsInPIE"))
	bool bApplyFrameRateSettingsInPIE = false;

	// 我们是否在PIE中应用前端特定的性能选项？
	// 它们驱动的大多数引擎性能/可伸缩性设置都是全局的，因此如果一个PIE窗口
	// 位于前端，另一个位于游戏中，一个将获胜，另一个将卡在这些设置中
	UPROPERTY(EditAnywhere, config, Category=PlatformEmulation, meta=(ConsoleVariable="Lyra.Settings.ApplyFrontEndPerformanceOptionsInPIE"))
	bool bApplyFrontEndPerformanceOptionsInPIE = false;

	// 我们是否应该在PIE中应用体验/平台模拟的设备配置文件？
	UPROPERTY(EditAnywhere, config, Category=PlatformEmulation, meta=(InlineEditConditionToggle, ConsoleVariable="Lyra.Settings.ApplyDeviceProfilesInPIE"))
	bool bApplyDeviceProfilesInPIE = false;

#if WITH_EDITOR
public:
	/**
	 * 由编辑器引擎调用，当有作弊激活时弹出提醒通知
	 */
	LYRAGAME_API void OnPlayInEditorStarted() const;

private:
	// 最后应用的模拟平台
	FName LastAppliedPretendPlatform;

private:
	/**
	 * 应用设置
	 */
	void ApplySettings();
	/**
	 * 更改活动的模拟平台
	 * @param NewPlatformName 新的平台名称
	 */
	void ChangeActivePretendPlatform(FName NewPlatformName);
#endif

public:
	//~UObject interface
#if WITH_EDITOR
	/**
	 * 属性更改后处理函数
	 * @param PropertyChangedEvent 属性更改事件
	 */
	virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
	/**
	 * 配置重新加载后处理函数
	 * @param PropertyThatWasLoaded 被加载的属性
	 */
	virtual void PostReloadConfig(FProperty* PropertyThatWasLoaded) override;
	/**
	 * 属性初始化后处理函数
	 */
	virtual void PostInitProperties() override;
#endif
	//~End of UObject interface

private:
	/**
	 * 获取已知平台ID列表
	 * @return 平台名称数组
	 */
	UFUNCTION()
	TArray<FName> GetKnownPlatformIds() const;

	/**
	 * 获取已知设备配置文件列表
	 * @return 设备配置文件名称数组
	 */
	UFUNCTION()
	TArray<FName> GetKnownDeviceProfiles() const;

	/**
	 * 选择一个合理的基础设备配置文件
	 */
	void PickReasonableBaseDeviceProfile();
};